/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import Common.CommonUtil;
import hibernate.entity.Account;
import hibernate.entity.Collection;
import hibernate.entity.PriceHistory;
import hibernate.entity.TrackedProduct;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.KeywordAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.util.Version;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;

/**
 *
 * @author NamDH
 */
public class TrackedProductDAO {

    private Session session;

    public TrackedProductDAO() {
        SessionFactory sf = Common.HibernateUtil.getSessionFactory();
        session = sf.getCurrentSession();
    }

    public List<TrackedProduct> getTrackedProductbyAccount_Id(int account_Id) {
        try {

            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct where AccountID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, account_Id);
            List<TrackedProduct> result = query.list();
            session.getTransaction().commit();
            return result;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return null;
    }

        public List<TrackedProduct> getTrackedProductbyAccountId(int account_Id) {
        try {
            List<TrackedProduct> trackedProductList = Collections.synchronizedList(new ArrayList<TrackedProduct>());
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "select tp.trackedProductId, tp.productLink, tp.desiredPrice from TrackedProduct As tp where tp.account.accountID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, account_Id);

            List result = query.list();
            for (int i= 0; i < result.size(); i++) {
                Object o[] = (Object[])result.get(i);
               TrackedProduct tp = new TrackedProduct(Integer.parseInt(o[0].toString()), String.valueOf(o[1]), Double.parseDouble(o[2].toString()));
               trackedProductList.add(tp);
            }
            
            session.getTransaction().commit();
            return trackedProductList;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return null;
    }
    public List<TrackedProduct> getTrackedProductbyCollection(int account_Id, int collection_Id) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct where AccountID = ? AND CollectionID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, account_Id);
            query.setInteger(1, collection_Id);
            List<TrackedProduct> result = query.list();
            session.getTransaction().commit();
            return result;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return null;
    }

    public TrackedProduct getTrackedProductbyProduct_ID(int product_Id) {
        TrackedProduct trackedProduct = new TrackedProduct();
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct where TrackedProductID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, product_Id);
            trackedProduct = (TrackedProduct) query.uniqueResult();
            session.getTransaction().commit();
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
            return null;
        }
        return trackedProduct;
    }

    public boolean deleteProduct(int trackedProductID) {
        try {

            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            TrackedProduct tp = (TrackedProduct) session.get(TrackedProduct.class, trackedProductID);
            session.delete(tp);
            session.flush();
            session.getTransaction().commit();
            return true;

        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
            return false;
        }
    }

    public List<TrackedProduct> searchProductLikeName(String productName) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct Where ProductName like ?";
            Query query = session.createQuery(sql);
            query.setString(0, "%" + productName + "%");
            List<TrackedProduct> result = query.list();
            session.getTransaction().commit();
            return result;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return null;
    }

    public List<TrackedProduct> searchProductLikeNameByAccount(String productName, int account_Id) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct Where ProductName like ? and AccountID = ?";
            Query query = session.createQuery(sql);
            query.setString(0, "%" + productName + "%");
            query.setInteger(1, account_Id);
            List<TrackedProduct> result = query.list();
            session.getTransaction().commit();
            return result;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return null;
    }

    public boolean addNewTrackedProduct(int accountId, String url, String productName,
            double productPrice, String productImage, double desiredPrice) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();

            Account account = (Account) session.get(Account.class, accountId);

            Collection collection = (Collection) session.get(Collection.class, 14);

            String trackedDate = CommonUtil.getCurrentTime();

            TrackedProduct trackedProduct = new TrackedProduct(account, collection, trackedDate, productName, productImage, url, desiredPrice);

            session.save(trackedProduct);

            PriceHistory pricehistory = new PriceHistory(trackedProduct, productPrice, trackedDate);

            session.save(pricehistory);
            session.flush();
            session.getTransaction().commit();
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    public List<TrackedProduct> getAllProductForUpdatePrice() {
        List<TrackedProduct> result = null;

        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "from TrackedProduct";
            Query query = session.createQuery(sql);
            result = query.list();
            session.getTransaction().commit();
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public boolean updateDesiredPrice(double desiredPrice, int trackedProductID) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            TrackedProduct tp = (TrackedProduct) session.get(TrackedProduct.class, trackedProductID);
            tp.setDesiredPrice(desiredPrice);
            session.update(tp);
            session.flush();
            session.getTransaction().commit();
            return true;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
            return false;
        }
    }

    public boolean removeProductFromCollection(int collectionID) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "update TrackedProduct set CollectionID = '14' where CollectionID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, collectionID);
            query.executeUpdate();
            session.flush();
            session.getTransaction().commit();
            return true;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
            return false;
        }
    }

    public boolean deleteTrackedProductbyAccountID(int accountID) {
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            String sql = "delete TrackedProduct where AccountID = ?";
            Query query = session.createQuery(sql);
            query.setInteger(0, accountID);
            query.executeUpdate();
            session.flush();
            session.getTransaction().commit();
            return true;
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
            return false;
        }
    }

    public List recommendProduct(String productName, String productLink) {
        SessionFactory sf = Common.HibernateUtil.getSessionFactory();
        session = sf.openSession();
        FullTextSession fts = Search.getFullTextSession(session);
        fts.getTransaction().begin();
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
        String searchQuery = QueryParser.escape("productName:" + productName);
        QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "productName", analyzer);
        org.apache.lucene.search.Query luceneQuery = null;
        try {
            luceneQuery = parser.parse(searchQuery);
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        Query query = fts.createFullTextQuery(luceneQuery, TrackedProduct.class);
        List<TrackedProduct> result = query.list();


        for (int i = 0; i < result.size(); i++) {
            TrackedProduct item = result.get(i);
            for (int j = 0; j < result.size(); j++) {
                if (j != i) {
                    if (item.getProductLink().equals(result.get(j).getProductLink())) {
                        result.remove(j);
                    }
                }

            }
        }


        for (int i = 0; i < result.size(); i++) {
            String link = result.get(i).getProductLink();
            if (link.equals(productLink)) {
                result.remove(i);
            }
        }

        if (result.size() > 4) {
            for (int i = 4; i < result.size();) {
                result.remove(4);
            }
        }

//        List result = query.list();
        fts.getTransaction().commit();
        return result;

    }

    public int countTrackedProduct() {
        int result = 0;
        try {
            SessionFactory sf = Common.HibernateUtil.getSessionFactory();
            session = sf.openSession();
            session.getTransaction().begin();
            Number number = (Number) session.createCriteria(TrackedProduct.class).setProjection(Projections.rowCount()).uniqueResult();
            result = number.intValue();
            session.getTransaction().commit();
        } catch (Exception e) {
            if (session.getTransaction().isActive()) {
                session.getTransaction().rollback();
            }
            e.printStackTrace();
        }
        return result;
    }
}
